package com.seezoon.domain.service.user;


import com.seezoon.domain.dao.mapper.UserInfoMapper;
import com.seezoon.domain.dao.mapper.UserProfileMapper;
import com.seezoon.domain.dao.po.UserInfoPO;
import com.seezoon.domain.dao.po.UserProfilePO;
import com.seezoon.domain.service.user.vo.UserRegisterTypeVO;
import com.seezoon.domain.service.user.vo.UserRegisterVO;
import com.seezoon.domain.service.user.vo.UserStatus;
import com.seezoon.infrastructure.error.ErrorCode;
import com.seezoon.infrastructure.exception.Assertion;
import com.seezoon.infrastructure.exception.ExceptionFactory;
import com.seezoon.infrastructure.security.PasswordEncoder;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import java.time.Instant;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

/**
 * 用户注册服务
 */
@RequiredArgsConstructor
@Slf4j
@Service
@Validated
public class UserRegisterService {

    private final UserInfoService userInfoService;
    private final UserInfoMapper userInfoMapper;
    private final UserProfileMapper userProfileMapper;

    @Transactional
    public UserInfoPO register(@Valid @NotNull UserRegisterVO vo) {
        UserInfoPO userInfoPO = userInfoMapper.selectByUsername(vo.getUsername());
        if (userInfoPO != null) {
            throw ExceptionFactory.bizException(ErrorCode.USER_ALREADY_EXISTS);
        }
        UserRegisterTypeVO.check(vo.getRegisterType());
        // 生成用户
        UserInfoPO user = new UserInfoPO();
        user.setUsername(vo.getUsername());
        user.setPassword(PasswordEncoder.encode(vo.getPassword()));
        user.setSecretKey(userInfoService.genSecretKey());
        user.setStatus(UserStatus.VALID.code());
        Instant now = Instant.now();
        user.setCreateTime(now);
        user.setUpdateTime(now);
        int affectedRows = userInfoMapper.insert(user);
        Assertion.affectedOne(affectedRows);
        Assertion.notNull(user.getUid(), "uid is null");
        // 保存用户信息
        UserProfilePO po = new UserProfilePO();
        po.setUid(user.getUid());
        if (UserRegisterTypeVO.isMobile(vo.getRegisterType())) {
            po.setMobile(user.getUsername());
        }
        if (UserRegisterTypeVO.isEmail(vo.getRegisterType())) {
            po.setEmail(user.getUsername());
        }
        po.setCreateTime(now);
        po.setUpdateTime(now);
        affectedRows = userProfileMapper.insert(po);
        Assertion.affectedOne(affectedRows);
        return user;
    }


}
